package com.shi.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.extension.toolkit.Db;
import com.shi.entity.po.Menu;
import com.shi.entity.po.Role2Menu;
import com.shi.entity.vo.MenuVO;
import com.shi.entity.vo.SimpleMenuVO;
import com.shi.mapper.MenuMapper;
import com.shi.service.MenuService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import static com.shi.constants.SysConstant.MENU_TREE_ROOT;

/**
 * (Menu)表服务实现类
 *
 * @author makejava
 * @since 2024-05-14 15:23:11
 */
@Service("menuService")
public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements MenuService {

    @Override
    public List<MenuVO> queryAllRoutes() {
        List<Menu> menus = baseMapper.selectList(null);
        menus = menus.stream().filter(menu -> menu.getMenuType().equals("M")).toList();
        return line2Tree(Menu.menu2MenuVOList(menus), MENU_TREE_ROOT);
    }

    @Override
    public List<MenuVO> queryAllMenuTree() {
        List<Menu> menus = baseMapper.selectList(null);
        return line2Tree(Menu.menu2MenuVOList(menus), MENU_TREE_ROOT);
    }

    @Override
    public List<Integer> queryFullCheckMenuIdByRoleId(Integer roleId) {
        List<Role2Menu> list = Db.lambdaQuery(Role2Menu.class)
                .eq(Role2Menu::getRoleId, roleId)
                .eq(Role2Menu::getFullCheck, 1)
                .list();
        return list.stream().map(Role2Menu::getMenuId).toList();
    }

    @Override
    public List<MenuVO> queryRoutesByAccountId(Integer accountId) {
        List<Menu> menus = baseMapper.selectByAccountId(accountId);
        menus = menus.stream().filter(menu -> menu.getMenuType().equals("M")).toList();
        return line2Tree(Menu.menu2MenuVOList(menus), MENU_TREE_ROOT);
    }

    @Override
    public List<String> queryAllMenuCode() {
        List<Menu> menus = baseMapper.selectList(null);
        if (menus == null || menus.isEmpty()) {
            return Collections.emptyList();
        }
        return menus.stream().map(Menu::getCode).toList();
    }

    /**
     * 线性表转树
     *
     * @param menuVOList
     * @param pid
     * @return
     */
    private List<MenuVO> line2Tree(List<MenuVO> menuVOList, Integer pid) {
        List<MenuVO> children = new ArrayList<>();
        for (MenuVO menuVO : menuVOList) {
            if (menuVO.getPid().equals(pid)) {
                menuVO.setChildren(line2Tree(menuVOList, menuVO.getMenuId()));
                children.add(menuVO);
            }
        }
        Collections.sort(children, Comparator.comparingInt(MenuVO::getOrderBy));
        return children;
    }


    @Override
    public List<String> queryMenuCodeByAccountId(Integer accountId) {
        List<Menu> menus = baseMapper.selectByAccountId(accountId);
        if (menus == null || menus.isEmpty()) {
            return Collections.emptyList();
        }
        return menus.stream().map(Menu::getCode).toList();
    }

    @Transactional
    @Override
    public void removeById(Integer menuId) {
        // 1. 删除权限
        baseMapper.deleteById(menuId);
        // 2. 删除角色权限关系
        Db.lambdaUpdate(Role2Menu.class)
                .eq(Role2Menu::getMenuId, menuId)
                .remove();
    }

    @Transactional
    @Override
    public void removeBatchByIds(List<Integer> ids) {
        // 1. 删除权限
        baseMapper.deleteBatchIds(ids);
        // 2. 删除角色权限关系
        Db.lambdaUpdate(Role2Menu.class)
                .in(Role2Menu::getMenuId, ids);
    }

    @Override
    public List<SimpleMenuVO> queryMenuByMenuType(String menuType) {
        List<Menu> menus = lambdaQuery().eq(Menu::getMenuType, menuType).list();
        return menus.stream().map(menu -> BeanUtil.toBean(menu, SimpleMenuVO.class)).toList();
    }


}
